package r3.cluster.router;

import r3.common.R3Url;
import r3.rpc.RpcRequest;
import r3.rpc.RpcRequestLauncher;
import r3.rpc.RpcResponse;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;

/**
 * DefaultRouter
 *
 * @author zhoufn
 * @create 2017-12-28 10:58
 **/
public class DefaultRouter implements Router{

    private static Executor executor = Executors.newCachedThreadPool();

    public static ExecutorCompletionService<RpcResponse> getCompletionService(){
        return new ExecutorCompletionService<>(executor);
    }

    @Override
    public List<RpcResponse> route(List<RouterEntity> entities) throws Exception {
        List<RpcResponse> rpcResponses = new ArrayList<>();
        ExecutorCompletionService<RpcResponse> executorCompletionService = getCompletionService();
        for(final RouterEntity entity : entities){
            executorCompletionService.submit(new Callable<RpcResponse>() {
                public RpcResponse call() throws Exception {
                    RpcRequestLauncher launcher = new RpcRequestLauncher(entity.getUrl().getApplicationHost(),entity.getUrl().getApplicationPort());
                    return launcher.launch(entity.getRequest());
                }
            });
        }
        for(RouterEntity entity : entities){
            RpcResponse rpcResponse = executorCompletionService.take().get();
            rpcResponses.add(rpcResponse);
        }
        return rpcResponses;
    }

}
